1 /////////////// Maximum flow for sparse graphs ///////////////
2 /////////////// Complexity: O(V * E^2) ///////////////
7 Create graph using add_edge(u, v, c);
8 max_flow(source, sink);
10 WARNING: The algorithm writes on the cap array. The capacity
11 is not the same after having run the algorithm. If you need
12 to run the algorithm several times on the same graph, backup
16 const int MAXE
= 50000; //Maximum number of edges
17 const int oo
= INT_MAX
/ 4;
25 Builds a directed edge (u, v) with capacity c.
26 Note that actually two edges are added, the edge
27 and its complementary edge for the backflow.
29 int add_edge(int u
, int v
, int c
){
30 adj
[current_edge
] = v
;
31 cap
[current_edge
] = c
;
32 next
[current_edge
] = first
[u
];
33 first
[u
] = current_edge
++;
35 adj
[current_edge
] = u
;
36 cap
[current_edge
] = 0;
37 next
[current_edge
] = first
[v
];
38 first
[v
] = current_edge
++;
41 void initialize_max_flow(){
43 memset(next
, -1, sizeof next
);
44 memset(first
, -1, sizeof first
);
50 //arrived_by[i] = The last edge used to reach node i
51 int find_augmenting_path(int src
, int snk
){
53 Make a BFS to find an augmenting path from the source to
54 the sink. Then pump flow through this path, and return
55 the amount that was pumped.
57 memset(arrived_by
, -1, sizeof arrived_by
);
62 while (h
< t
&& arrived_by
[snk
] == -1){ //BFS
64 for (int e
= first
[u
]; e
!= -1; e
= next
[e
]){
66 if (arrived_by
[v
] == -1 && cap
[e
] > 0){
68 incr
[v
] = min(incr
[u
], cap
[e
]);
74 if (arrived_by
[snk
] == -1) return 0;
79 //Remove capacity from the edge used to reach node "cur"
80 //Add capacity to the backedge
81 cap
[arrived_by
[cur
]] -= neck
;
82 cap
[arrived_by
[cur
] ^ 1] += neck
;
83 //move backwards in the path
84 cur
= adj
[arrived_by
[cur
] ^ 1];
89 int max_flow(int src
, int snk
){
91 while ((neck
= find_augmenting_path(src
, snk
)) != 0){